package com.wolfpire.knowledge.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.wolfpire.knowledge.dao.KnowledgeDao;
import com.wolfpire.subject.dao.SubjectDao;
import com.wolfpire.system.common.Constants;
import com.wolfpire.system.common.Page;
import com.wolfpire.system.common.base.dao.impl.BaseHibernateDao;
import com.wolfpire.system.dao.UserDao;
import com.wolfpire.system.model.DataDict;
import com.wolfpire.system.model.Knowledge;
import com.wolfpire.system.model.Profession;
import com.wolfpire.system.model.Subject;
import com.wolfpire.system.model.User;

@Repository("knowledgeDao")
public class KnowledgeDaoImpl extends BaseHibernateDao<Knowledge, Long> implements KnowledgeDao {

	public List<Knowledge> list(Knowledge knowledge) {
		Criteria c = createCriteria(createFilter(knowledge));
		return c.list();
	}

	public Page<Knowledge> findKnowledges(Page<Knowledge> page,
			Knowledge filterKnowledge) {
		/*Criterion[] criterions = this.createFilter(filterKnowledge);
		int totalCount = this.findIntByCriteria(criterions);
		page.setTotalCount(totalCount);
		if (0 < totalCount) {
			Criteria c = createCriteria(criterions);
			//c.addOrder(Order.asc("seq"));
			c.addOrder(Order.asc("id"));
			c = setPageParameter(c, page);
			@SuppressWarnings("unchecked")
			List<Knowledge> knowledges = c.list();
			page.setDataList(knowledges);
		}
		return page;*/
		StringBuffer querySqlBuffer = new StringBuffer();
		StringBuffer countSqlBuffer = new StringBuffer();
		List<String> propertyNames = new ArrayList<String>();
		List propertyValues = new ArrayList();
		//querySqlBuffer.append(" SELECT u.* FROM t_sm_user u, t_sm_org o, t_sm_user_org uo ")
		querySqlBuffer.append(" SELECT k.* FROM t_knowledge k  ")
				.append(" LEFT JOIN t_subject_knowledge sk ON k.id = sk.knowledge_id  ")
				.append(" LEFT JOIN t_subject_knowledge s ON s.id = sk.subject_id ")
				.append(" LEFT JOIN t_profession_subject ps ON ps.subject_id = sk.subject_id ")
				.append(" WHERE 1 =1 ");
				//.append(" WHERE u.id = uo.user_id AND uo.org_id = o.id ");
		if (null != filterKnowledge.getId()) {
			querySqlBuffer.append(" k.id =:id");
			propertyNames.add("id");
			propertyValues.add(filterKnowledge.getId());
		}
		
		if (null != filterKnowledge.getParentId()) {
			querySqlBuffer.append(" k.parentId =:parentId");
			propertyNames.add("parentId");
			propertyValues.add(filterKnowledge.getParentId());
		}
		if (!StringUtils.isBlank(StringUtils.stripToEmpty(filterKnowledge.getName()))) {
			querySqlBuffer.append(" AND k.name LIKE :name ");
			propertyNames.add("name");
			propertyValues.add("%" + StringUtils.stripToEmpty(filterKnowledge.getName()) + "%");
		}
		
		if (null != filterKnowledge.getSubjectId()) {
			querySqlBuffer.append(" AND sk.subject_id= :subjectId ");
			propertyNames.add("subjectId");
			propertyValues.add(filterKnowledge.getSubjectId());
		}
		
		if (null != filterKnowledge.getProfessionId()) {
			querySqlBuffer.append(" AND ps.profession_id =:professionId ");
			propertyNames.add("professionId");
			propertyValues.add(filterKnowledge.getProfessionId());
		}
		
		countSqlBuffer.append(" SELECT count(1) from (").append(querySqlBuffer).append(") AS TOTAL ");
		int totalCount = this.findSqlInt(countSqlBuffer.toString(), propertyNames, propertyValues);
		page.setTotalCount(totalCount);
		querySqlBuffer.append(" ORDER BY s.id DESC ");
		if (0 < totalCount) {
			List<Knowledge> result = this.setPageParameter(page, Knowledge.class, querySqlBuffer.toString(), propertyNames, propertyValues);
			page.setDataList(result);
		}
		
		return page;
	}

	public Knowledge getByName(String name) {
		Criterion[] criterions = new Criterion[]{
				Restrictions.eq("name", name)
		};
		return findUniqueByCriteria(criterions);
	}
	
	private Criterion[] createFilter(Knowledge knowledge) {
		if (null == knowledge) {
			return null;
		}
		List<Criterion> criterions = new ArrayList<Criterion>();
		if (null != knowledge.getId()) {
			criterions.add(Restrictions.eq("id", knowledge.getId()));
		}
		if (null != knowledge.getParentId()) {
			criterions.add(Restrictions.eq("parentId", knowledge.getParentId()));
		}/* else {
			criterions.add(Restrictions.isNull("parentId"));
		}*/
		if (!StringUtils.isBlank(knowledge.getName())) {
			criterions.add(Restrictions.like("name", knowledge.getName(), MatchMode.ANYWHERE));
		}
		
		if (!StringUtils.isBlank(knowledge.getJoinname())) {
			criterions.add(Restrictions.like("joinname", knowledge.getJoinname(), MatchMode.ANYWHERE));
		}
		
		/*if(null != knowledge.getSubjectId()){
			criterions.add(Restrictions.eq("subjectId", knowledge.getSubjectId()));
		}*/
		return criterions.toArray(new Criterion[criterions.size()]);
	}

}
